package com.hht.baselibs.dialog

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.PixelFormat
import android.os.Bundle
import android.util.DisplayMetrics
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import androidx.annotation.StyleRes
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentTransaction
import com.hht.baselibs.util.ViewUtils


/**
 * Author:chen'hu
 * Time:2023/8/9 11:26
 * Description:This is BaseDialog
 */
abstract class BaseDialog : DialogFragment() {
    protected var mLayoutResId: Int = 0
    private var mMargin = 0//边距
    private var mAnimStyle = 0//动画
    private lateinit var mContext: Context
    private var mWidth = 0
    private var mHeight = 0
    private var mOutCancel = true //点击外部取消


    override fun onAttach(context: Context) {
        super.onAttach(context)
        mContext = context
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setStyle(STYLE_NO_TITLE, theme)
        mLayoutResId = getLayoutResId()
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        if (mLayoutResId < 1) {
            throw NullPointerException("layout is not null ...")
        }
        val view = inflater.inflate(mLayoutResId, container, false)
        convertView(ViewUtils.create(view), this)
        return view
    }

    override fun onStart() {
        super.onStart()
        initView()
    }

    fun showDialog(manager: FragmentManager, tag: String): BaseDialog {
        val ft: FragmentTransaction = manager.beginTransaction()
        val fragmentByTag: Fragment? = manager.findFragmentByTag(tag)
        if (fragmentByTag != null) {
            //防止过快点击重复弹出报错
            if (fragmentByTag.isAdded) return this
            ft.show(fragmentByTag)
        } else {
            showAllowingLoss(manager, tag)
        }
        return this
    }

    /**
     * 解决 Can not perform this action after onSaveInstanceState问题
     *
     * @param manager FragmentManager
     * @param tag     tag
     */
    private fun showAllowingLoss(manager: FragmentManager, tag: String?) {
        try {
            val cls: Class<*> = DialogFragment::class.java
            val mDismissed = cls.getDeclaredField("mDismissed")
            mDismissed.isAccessible = true
            mDismissed[this] = false
            val mShownByMe = cls.getDeclaredField("mShownByMe")
            mShownByMe.isAccessible = true
            mShownByMe[this] = true
        } catch (e: Exception) {
            //调系统的show()方法
            show(manager, tag)
            return
        }
        val ft = manager.beginTransaction()
        ft.add(this, tag)
        ft.commitAllowingStateLoss()
    }

    @SuppressLint("NewApi")
    private fun initView() {
        val window = dialog!!.window
        if (window != null) {
            val params = window.attributes
            params.format = PixelFormat.TRANSPARENT

            //设置宽度
            if (mWidth == 0) {
                params.width = getScreenWidth(mContext) - 2 * mMargin
            } else {
                params.width = mWidth
            }
            //设置高度
            if (mHeight == 0) {
                params.height = getScreenHeight(mContext)
            } else {
                params.height = mHeight
            }

            //设置动画
            if (mAnimStyle != 0) {
                window.setWindowAnimations(mAnimStyle)
            }
            window.attributes = params
        }
        isCancelable = mOutCancel
    }

    /**
     * 设置宽高
     *
     * @param width
     * @param height
     * @return
     */
    fun setSize(width: Int, height: Int): BaseDialog {
        mWidth = width
        mHeight = height
        return this
    }

    /**
     * 设置margin
     *
     * @param margin
     * @return
     */
    fun setMargin(margin: Int): BaseDialog {
        mMargin = margin
        return this
    }

    /**
     * 设置进入退出动画
     *
     * @param animStyle
     * @return
     */
    fun setAnimStyle(@StyleRes animStyle: Int): BaseDialog {
        mAnimStyle = animStyle
        return this
    }

    /**
     * 设置是否点击外部取消
     * @param outCancel
     * @return
     */
    fun setOutCancel(outCancel: Boolean): BaseDialog {
        mOutCancel = outCancel
        return this
    }

    protected abstract fun getLayoutResId(): Int

    /**
     * 操作dialog布局
     *
     * @param holder
     * @param dialog
     */
    abstract fun convertView(holder: ViewUtils, dialog: BaseDialog)


    /**
     * 获取屏幕宽度
     */
    fun getScreenWidth(context: Context): Int {
        val wm = context
            .getSystemService(Context.WINDOW_SERVICE) as WindowManager
        val outMetrics = DisplayMetrics()
        wm.defaultDisplay.getMetrics(outMetrics)
        return outMetrics.widthPixels
    }

    /**
     * 获取屏幕高度
     */
    fun getScreenHeight(context: Context): Int {
        val wm = context
            .getSystemService(Context.WINDOW_SERVICE) as WindowManager
        val outMetrics = DisplayMetrics()
        wm.defaultDisplay.getMetrics(outMetrics)
        return outMetrics.heightPixels
    }

}